package com.infinitegroup.findmystuff.presenters;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import android.content.Context;
import com.infinitegroup.findmystuff.models.Account;
import com.infinitegroup.findmystuff.models.AccountLink;
import com.infinitegroup.findmystuff.models.Item;
import com.infinitegroup.findmystuff.models.ItemLink;
import com.infinitegroup.findmystuff.views.HomeView;

/**
 * This class controls the Home Screen in the application.
 * @author Rohit
 *
 */
public class HomePresenter{
	
	private Account account; // this is the account passed in by the login screen.
	private Item itemLink;
	private HomeView view;
	private List<ListItem> items;
	private int indexClicked;
	
	/**
	 * Constructor for the HomePresenter.
	 * @param view The view associated with the activity this presenter controls.
	 * @param username Username of the account currently logged into.
	 */
	public HomePresenter(HomeView view, String username){
		this.view = view;
		itemLink = new ItemLink((Context) view);
		account = new AccountLink(username, (Context) view); // establish a new account link with the username passed in.
															// this also populates all account fields, as a username is passed in.
		try{
			account.refresh(account.getUsername());
			List<Map<String,String>> rawList = account.getAccountItems();
			items = generateListItems(rawList);
		} catch (Exception e){
			view.displayMessage("Could not fetch items from database");
		}
	}
	
	/**
	 * Creates the list of items to display
	 * @param rawList List to add items into
	 * @return List containing all items to display
	 */
	private List<ListItem> generateListItems(List<Map<String,String>> rawList){
		List<ListItem> items = new LinkedList<ListItem>();
	 	if (rawList!=null){
	 		for (Map<String, String> m : rawList){
	 			items.add(new ListItem(m.get(Constants.ITEM_ID), m.get(Constants.ITEM_ITEMNAME), 
	 					m.get(Constants.ITEM_LOCATION), m.get(Constants.ITEM_STATUS), m.get(Constants.ITEM_CATEGORY)));
	 		}
	 	}
	 	return items;
	}
	
	/**
	 * Handles the clicking of an item in the list.
	 * @param index Location of the item clicked in the list.
	 */
	public void handleItemClick(int index){
		if (!items.get(index).status.equals(Constants.ITEM_STATUS_FOUND)){
			String location = items.get(index).location;
			String category = items.get(index).category;
			List<Map<String,String>> rawList = itemLink.getItemsFilteredBy(null, location, Constants.ITEM_STATUS_FOUND, category, null);
			List<ListItem> matches = generateListItems(rawList); // prepare a new list of matching items
			view.displayMatches(matches); //give it to the view to display.
		} else {
			view.displayMessage("You found this item, and did not lose it. The person seeking this item will contact you.");
		}
	}
	
	/**
	 * Handles resume by getting the items to display and giving it to the view.
	 */
	public void handleResume(){
		account.refresh(account.getUsername());
		items = generateListItems(account.getAccountItems()); // get items again (inefficient)
		view.setItemsList(items); // give it to the view.
	}
	
	/**
	 * Handles a click of the add item button by telling the view to advance
	 * to the add item screen.
	 */
	public void handleAddItemClick(){
		view.advanceToAddItemView(account.getUsername());
	}
	
	/**
	 * Unused method.
	 */
	public void handleDeleteItemsClick(){
		
	}
	
	/**
	 * Handles a click of the logout button by telling the view to
	 * advance to the login screen and to end the activity.
	 */
	public void handleLogoutClick(){
		view.advanceToLogin();
		view.end();
	}

	/**
	 * Gets the first name of the account.
	 * @return First name assoicated with the account currently logged into
	 */
	public String getFirstName() {
		return account.getFirstName();
	}

	/**
	 * Handles the a click of the search button by telling the view to 
	 * advance to the view all screen.
	 */
	public void handleSeeAllItemsClick() {
		view.advanceToViewAllView();
	}
	
	/**
	 * This class is just a proper container of 'Items' that are fetched as maps.
	 * It provides a more formal wrapper that the view can use.
	 * It's main purpose is to have a custom toString() method.
	 *
	 */
	public class ListItem {
		private String itemId, itemName, location, status, category;
		private String stringRepresentataion; 
		
		private ListItem(String itemId, String itemName, String location, String status, String category){
			this.itemId = itemId;
			this.itemName = itemName;
			this.location = location;
			this.status = status;
			this.category = category;
			this.stringRepresentataion = generateStringValue(itemName, location, status, category);
		}
		
		private String generateStringValue(String itemName, String location, String status, String category){
			return itemName + " | " + category + "\n" + status  + " | " + location;
		}
		
		public String toString(){
			return stringRepresentataion; 
		}
	}

	/**
	 * Returns the list of items to display.
	 * @return List of items to display
	 */
	public List<ListItem> getNewItems() {
		return items;
	}

	/**
	 * Gets items associated with the username and returns them as a list of maps.
	 * @return List of items (maps).
	 */
	public List<Map<String,String>> getItemsToDisplay() {
		try{
			account.refresh(account.getUsername());
			List<Map<String,String>> items = account.getAccountItems();
			if (items.isEmpty()){
				return null;
			} else {
				return items;
			}
		} catch (Exception e){
			view.displayMessage("Could not fetch items from database");
			return null;
		}
	}
}
